<?php

namespace App\Robot\Service;

use App\Common\Constants\StorageModeConstants;
use App\Common\Helpers\CommonUpload;
use App\CustHub\Constants\MsgTypeConstants;
use App\CustHub\Helpers\WxDownload;
use App\CustHub\Model\ChRobot;
use FriendsOfHyperf\Lock\Exception\LockTimeoutException;
use GuzzleHttp\Client;
use Hyperf\Coroutine\Coroutine;
use Hyperf\Guzzle\CoroutineHandler;
use App\Common\Robot\Contracts\GatewayInterface;
use App\Common\Robot\Robot;
use Nette\Utils\Random;
use function FriendsOfHyperf\Lock\lock;

class RobotMsgService
{
    public function processMessages(ChRobot $robot,$msgType,$data)
    {
        $robotApiService = make(Robot::class,[$robot->server_id,$robot->uuid])->gateway();
        $url = '';

        $lock = lock('down_file_to_oss_lock:'.json_encode($data['msg_data']),10);
        try {
            $lock->block(4);
            switch ($msgType) {
                case MsgTypeConstants::IMAGE:
                    $url = $this->processImagesMessage($robotApiService,$data);
                    break;
                case MsgTypeConstants::VIDEO:
                    $url = $this->processVideoMessage($robotApiService,$data);
                    break;
                case MsgTypeConstants::FILE:
                    $url = $this->processFileMessage($robotApiService,$data);
                    break;
                case MsgTypeConstants::EMOJI:
                    $url = $this->processEmojiMessage($data['msg_data']);
                    break;
                case MsgTypeConstants::URL:
                    $url = $this->processUrlIconMessage($robotApiService,$data);
                    break;
                default:
                    break;
            }
            return $url;
        } catch (LockTimeoutException $e) {
            return '';
        } finally {
            $lock->release();
        }
    }


    private function processUrlIconMessage(GatewayInterface $robotApiService,$data)
    {
        $msgData = $this->changeMsgData($data['msg_data']);

        $fileName = !empty($msgData['file_name']) ? base64_decode($msgData['file_name']) : Random::generate(20).'.jpg';
        if(!empty($msgData['icon_aes_key']) && !empty($msgData['icon_auth_key']) && !empty($msgData['icon_url'])){
            //$result=$this->getWxFilePath($msgData['icon_url'], $msgData['icon_aes_key'], $msgData['icon_auth_key'], $msgData['icon_size'], $fileName);
            $result = $robotApiService->wxDownload($msgData['icon_aes_key'],$msgData['icon_auth_key'],$msgData['icon_size'],$msgData['icon_url'],2,$fileName);
            if($result !== false){
                return $result['url'];
            }
        }

        return '';
    }

    private function processImagesMessage(GatewayInterface $robotApiService,$data)
    {
        $msgData = $this->changeMsgData($data['msg_data']);

        $fileName = !empty($msgData['file_name']) ? base64_decode($msgData['file_name']) : Random::generate(20).'.jpg';
        if($data['msgtype'] == 14){
            if($msgData['image_has_hd']){
                $fileType = 1;
            }else{
                $fileType = 2;
            }
            //下载企微文件
            $result = $robotApiService->wxWorkDownload($msgData['file_aes_key'],$msgData['file_id'],$msgData['file_size'],$fileType,$fileName);
        }else{
//            if($msgData['image_has_hd']){
//                $fileType = 1;
//                $fileSize = $msgData['file_big_size'];
//                $fileUrl = $msgData['file_big_http_url'];
//            }else{
//                $fileType = 2;
//                $fileSize = $msgData['file_middle_size'];
//                $fileUrl = $msgData['file_middle_http_url'];
//            }
            $fileType = 2;
            $fileSize = $msgData['file_middle_size'];
            $fileUrl = $msgData['file_middle_http_url'];
            //下载个微文件
            $result = $robotApiService->wxDownload($msgData['file_aes_key'],$msgData['file_auth_key'],$fileSize,$fileUrl,$fileType,$fileName);
            //$result=$this->getWxFilePath($fileUrl, $msgData['file_aes_key'], $msgData['file_auth_key'], $fileSize, $fileName);
        }

        if($result !== false){
            return $result['url'];
        }

        return '';
    }

    private function processVideoMessage(GatewayInterface $robotApiService,$data)
    {
        $msgData = $this->changeMsgData($data['msg_data']);

        $fileName = !empty($msgData['file_name']) ? base64_decode($msgData['file_name']) : Random::generate(20).'.mp4';
        if($data['msgtype'] == 23){
            $result = $robotApiService->wxWorkDownload($msgData['file_aes_key'],$msgData['file_id'],$msgData['file_size'],4,$fileName);
        }else{
            $fileSize = $msgData['file_size'];
            //$result=$this->getWxFilePath($msgData['file_http_url'], $msgData['file_aes_key'], $msgData['file_auth_key'], $fileSize, $fileName);
            $result = $robotApiService->wxDownload($msgData['file_aes_key'],$msgData['file_auth_key'],$msgData['file_size'],$msgData['file_http_url'],4,$fileName);
        }
        if($result !== false){
            return $result['url'];
        }
        return '';
    }

    private function processFileMessage(GatewayInterface $robotApiService,$data)
    {
        $msgData = $this->changeMsgData($data['msg_data']);
        $fileName = !empty($msgData['file_name']) ? base64_decode($msgData['file_name']) : Random::generate(20).($msgData['file_name_ext'] ?? '');
        if($data['msgtype'] == 15){
            $result = $robotApiService->wxWorkDownload($msgData['file_aes_key'],$msgData['file_id'],$msgData['file_size'],5,$fileName);
        }else{
            //$fileSize = $msgData['file_size'];
            //$result=$this->getWxFilePath($msgData['file_http_url'], $msgData['file_aes_key'], $msgData['file_auth_key'], $fileSize, $fileName);
            $result = $robotApiService->wxDownload($msgData['file_aes_key'],$msgData['file_auth_key'],$msgData['file_size'],$msgData['file_http_url'],5,$fileName);
        }
        if($result !== false){
            return $result['url'];
        }
        return '';
    }

    private function processEmojiMessage($data)
    {
        $key = 'upload_emoji_to_oss_v1:'.$data['file_http_url'];
        $redis = redis();
        $url = $redis->get($key);
        if(empty($url)){
            $extension= $this->getImageExtension($data['file_http_url']);
            $imageContent = file_get_contents($data['file_http_url']);
            $url = container()->get(CommonUpload::class)->setStorageMode(StorageModeConstants::OSS)->uploadWrite($imageContent,'',$extension);
            $url = config('file.storage.oss.domain','') . $url;
            $redis->set($key,$url,30 * 24 * 60 * 60);
        }
        return $url;
    }

    private function getImageExtension(string $url): ?string
    {
        $handler = null;
        if (Coroutine::inCoroutine()) {
            $handler = new CoroutineHandler();
        }
        $client = new Client([
            'verify' => false, // 忽略 SSL 证书问题（如有）
            'timeout' => 3,
            'handler' => $handler,
        ]);

        try {
            $response = $client->head($url);
            $contentType = $response->getHeaderLine('Content-Type');
            // 映射 MIME 类型到扩展名
            $map = [
                'image/jpeg' => 'jpg',
                'image/png' => 'png',
                'image/gif' => 'gif',
                'image/webp' => 'webp',
                'image/bmp' => 'bmp',
                'image/svg+xml' => 'svg',
            ];

            return $map[$contentType] ?? 'gif';
        } catch (\Throwable $e) {
            // 失败处理
            return 'gif';
        }
    }

    private function changeMsgData(array $msgData): array
    {
        if(isset($msgData['file_aeskey'])){
            $msgData['file_aes_key'] = $msgData['file_aeskey'];
        }

        if(isset($msgData['file_authkey'])){
            $msgData['file_auth_key'] = base64_decode($msgData['file_authkey']);
        }

        if(isset($msgData['filename'])){
            $msgData['file_name'] = $msgData['filename'];
        }

        return $msgData;
    }
    public function getWxFilePath($url, $aesKey, $authKey, $fileSize,$fileName):mixed
    {
        try {
            $extension = pathinfo($fileName, PATHINFO_EXTENSION);
            $directory    = BASE_PATH . '/public/uploadfile';
            if (!is_dir($directory)) {
                mkdir($directory, 0755, true);
            }
            $dstPath    = $directory."/".$fileName;
            container()->get(WxDownload::class)->wxDownload($url, $aesKey, $authKey, $fileSize, $dstPath);
            $imageContent = file_get_contents($dstPath);
            $url = container()->get(CommonUpload::class)->setStorageMode(StorageModeConstants::OSS)->uploadWrite($imageContent,'',$extension);
            unlink($dstPath);
            return ['url'=>config('file.storage.oss.domain','').$url];
        }catch (\Exception $e){
            logger()->info("流片段下载失败:".$e->getMessage());
            return false;
        }
    }
}